package com.sdkj.recruit.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.geo.Sphere;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.sdkj.recruit.dao.ICompanyDao;
import com.sdkj.recruit.dao.IMongodbDAO;
import com.sdkj.recruit.model.Company;
import com.sdkj.recruit.model.CompanyEnvironment;
import com.sdkj.recruit.model.CompanyResume;
import com.sdkj.recruit.model.EducationalExperience;
import com.sdkj.recruit.model.Label;
import com.sdkj.recruit.model.Paginate;
import com.sdkj.recruit.model.Position;
import com.sdkj.recruit.model.PositionCollection;
import com.sdkj.recruit.model.Resume;
import com.sdkj.recruit.model.WorkExperience;
import com.sdkj.recruit.mongoSupport.QueryParamCreator;
import com.sdkj.recruit.util.StringUtil;

@Persistent
@Service("companyDao")
public class CompanyDao implements ICompanyDao {

	@Autowired
	private IMongodbDAO dao;

	@Override
	public void saveCompany(Company map) {
		dao.saveOrUpdatePO(map);
	}

	@Override
	public Company queryCompanyById(String companyId) {
		return dao.getPO(Company.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public void deleteCompany(String companyId) {
		dao.deletePOList(Company.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public List<Company> queryCompanyList(int pageNo, int pageSize, int companyType) {

		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "createDate");
		orders.add(order);

		List<Criteria> condList = new ArrayList<Criteria>();

		if(companyType<2) {
			condList.add(QueryParamCreator.eq("companyType",companyType));
		}
		condList.add(QueryParamCreator.isNotEmpty("companyId"));
		return dao.getPOList(Company.class, new Paginate(pageNo, pageSize), orders,
				(Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public long queryAllCompanyCount(int companyType) {
		List<Criteria> condList = new ArrayList<Criteria>();
		if(companyType<2) {
			condList.add(QueryParamCreator.eq("companyType",companyType));
		}
		return dao.getRowCount(Company.class, (Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public Company queryCompanyByMobile(String mobile) {
		return dao.getPO(Company.class, QueryParamCreator.eq("mobile", mobile));
	}

	@Override
	public void updatePassword(String mobile, String password) {
		
		Map<String,Object> map  =new HashMap<String,Object>();
		map.put("password", password);
		dao.saveOrUpdateDocument(Company.class, map, QueryParamCreator.eq("mobile", mobile));
	}

	@Override
	public void saveOrUpdateDocument(Class<Company> class1, Map<String, Object> map, Criteria eq) {
		dao.saveOrUpdateDocument(class1, map, eq);
	}

	@Override
	public List<Resume> queryResumeList(int pageNo, int pageSize, String workYearType) {
		
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "createDate");
		orders.add(order);
		
		List<Criteria> condList = new ArrayList<Criteria>();
		condList.add(QueryParamCreator.isNotNull("userId"));
		condList.add(QueryParamCreator.isNotNull("userName"));
		if(StringUtil.isNotEmptyString(workYearType)) {
			
			// 应届生
			if("1".equals(workYearType)) {
				condList.add(QueryParamCreator.eq("workYear", 0));
			}
			
			if("2".equals(workYearType)) {
				condList.add(QueryParamCreator.le("workYear", 1));
			}
			
			if("3".equals(workYearType)) {
				condList.add(QueryParamCreator.le("workYear", 3));
			}
			if("4".equals(workYearType)) {
				condList.add(QueryParamCreator.between("workYear", 3, 5));
			}
			if("5".equals(workYearType)) {
				condList.add(QueryParamCreator.between("workYear", 5, 10));
			}
			if("6".equals(workYearType)) {
				condList.add(QueryParamCreator.ge("workYear", 10));
			}
		}
		return dao.getPOList(Resume.class, new Paginate(pageNo, pageSize), orders, (Criteria[]) condList.toArray(new Criteria[0]));
		
	}

	@Override
	public long queryResumeList(String workYearType) {
		

		List<Criteria> condList = new ArrayList<Criteria>();
		condList.add(QueryParamCreator.isNotNull("userId"));
		condList.add(QueryParamCreator.isNotNull("userName"));

		// 应届生
		if("1".equals(workYearType)) {
			condList.add(QueryParamCreator.eq("workYear", 0));
		}
		
		if("2".equals(workYearType)) {
			condList.add(QueryParamCreator.le("workYear", 1));
		}
		
		if("3".equals(workYearType)) {
			condList.add(QueryParamCreator.le("workYear", 3));
		}
		if("4".equals(workYearType)) {
			condList.add(QueryParamCreator.between("workYear", 3, 5));
		}
		if("5".equals(workYearType)) {
			condList.add(QueryParamCreator.between("workYear", 5, 10));
		}
		if("6".equals(workYearType)) {
			condList.add(QueryParamCreator.ge("workYear", 10));
		}
		return dao.getRowCount(Resume.class, (Criteria[]) condList.toArray(new Criteria[0]));
	}

	@Override
	public List<CompanyResume> queryDeliverResumeList(int pageNo, int pageSize, String keyWord,String companyId) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "deliverDate");
		orders.add(order);
		return dao.getPOList(CompanyResume.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.isNotNull("userId"),QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public long queryAllDeliverResumeCount(String keyWord,String companyId) {
		return dao.getRowCount(CompanyResume.class, QueryParamCreator.isNotNull("userId"),QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public Resume queryResumeById(String resumeId) {
		return dao.getPO(Resume.class, QueryParamCreator.eq("resumeId", resumeId));
	}

	@Override
	public void savePosition(Position map) {
		dao.saveOrUpdatePO(map);;
	}

	@Override
	public List<Position> queryPositionList(int pageNo, int pageSize, String keyWord, String companyId) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "deliverDate");
		orders.add(order);
		return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders,
				QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public long queryAllPositionCount(String keyWord, String companyId) {
		return dao.getRowCount(Position.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public WorkExperience queryWorkExperienceById(String id) {
		return dao.getPO(WorkExperience.class, QueryParamCreator.eq("_id", id));
		
	}

	@Override
	public EducationalExperience queryEducationalExperienceById(String id) {
		// TODO Auto-generated method stub
		return dao.getPO(EducationalExperience.class, QueryParamCreator.eq("_id", id));
	}

	@Override
	public Position queryPositionById(String id) {
		return dao.getPO(Position.class, id);
	}

	@Override
	public List<Position> queryPositionList(int pageNo, int pageSize, String companyId) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "deliverDate");
		orders.add(order);
		return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders,
				QueryParamCreator.eq("companyId", companyId),QueryParamCreator.eq("positionSttaus",0));
	}

	@Override
	public long queryAllPositionCount(String companyId) {
		return dao.getRowCount(Position.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public void updatePosition(Position position) {
		dao.saveOrUpdatePO(position);
	}

	@Override
	public void collection(PositionCollection p) {
		dao.saveOrUpdatePO(p);
	}

	@Override
	public List<PositionCollection> querycollectionList(int pageNo, int pageSize, String userId) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "collectionDate");
		orders.add(order);
		return dao.getPOList(PositionCollection.class, new Paginate(pageNo, pageSize), orders,
				QueryParamCreator.eq("userId", userId));
	}

	@Override
	public long queryAllCollectionCount(String userId) {
		// TODO Auto-generated method stub
		return dao.getRowCount(PositionCollection.class, QueryParamCreator.eq("userId", userId));
	}

	@Override
	public PositionCollection queryCollectionById(String positionId, String userId) {
		return dao.getPO(PositionCollection.class, QueryParamCreator.eq("positionId", positionId),QueryParamCreator.eq("userId", userId));
	}

	@Override
	public void updateStatus(String id, int status) {
		Map<String,Object> map  =new HashMap<String,Object>();
		map.put("positionSttaus", status);
		dao.saveOrUpdateDocument(Position.class, map, QueryParamCreator.eq("_id", id));
	}

	@Override
	public void deleteCollection(String userId, String positionId) {
		dao.deletePOList(PositionCollection.class, QueryParamCreator.eq("positionId", positionId),QueryParamCreator.eq("userId", userId));
	}

	@Override
	public List<CompanyResume> deliverList(int pageNo, int pageSize, String userId) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "deliverDate");
		orders.add(order);
		return dao.getPOList(CompanyResume.class, new Paginate(pageNo, pageSize), orders,
				QueryParamCreator.eq("userId", userId));
	}

	@Override
	public List<Label> queryCompanyLableList(String companyId) {
		
		return dao.getPOList(Label.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public void updateCompany(Map<String, Object> maps, String companyId) {
		dao.saveOrUpdateDocument(Company.class, maps, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public List<Position> queryPositionList(int pageNo, int pageSize, int queryType,String keyword) {
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "createDate");
		orders.add(order);
		
		if(queryType>1) {
			if(queryType==2) {
				return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.isNotEmpty("companyId"),QueryParamCreator.eq("positionSttaus",0));
			}
			if(queryType==3) {
				
				if(StringUtil.isNotEmptyString(keyword)) {
					return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.isNotEmpty("companyId"),QueryParamCreator.like("positionName", keyword),QueryParamCreator.eq("positionSttaus",0));
				}else {
					return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.isNotEmpty("companyId"),QueryParamCreator.eq("positionSttaus",0));
				}
			}
		}
		return dao.getPOList(Position.class, new Paginate(pageNo, pageSize), orders, QueryParamCreator.eq("hotPosition", 1));
	}

	@Override
	public void addCount(String id) {
		dao.updateInc(Position.class, "viewCount", 1, QueryParamCreator.eq("_id", id));
	}

	@Override
	public List<WorkExperience> queryWorkExperienceByResumeId(String resumeId) {
		return dao.getPOList(WorkExperience.class, QueryParamCreator.eq("resumeId", resumeId));
	}

	@Override
	public List<EducationalExperience> queryEducationalExperienceByResumeId(String resumeId) {
		return dao.getPOList(EducationalExperience.class, QueryParamCreator.eq("resumeId", resumeId));
	}

	@Override
	public void saveCompanyPic(List<CompanyEnvironment> list) {
		dao.saveOrUpdatePOList(list);
	}

	@Override
	public List<CompanyEnvironment> queryCompanyEnvironmentByCompanyId(String companyId) {
		return dao.getPOList(CompanyEnvironment.class, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public List<Company> queryNearbyCompany(int pageNo, int pageSize, String longitude, String latitude, int distance) {
		
		List<Criteria> params = new ArrayList<Criteria>();
		params.add(QueryParamCreator.eq("compamnyAuthentication", 1));
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "createDate");
		orders.add(order);
		if (StringUtil.isNotEmptyString(longitude) && StringUtil.isNotEmptyString(latitude) && distance > 0) {
			Point point = new Point(Double.valueOf(longitude), Double.valueOf(latitude));
			//Distance d = new Distance(Double.valueOf(distance)* 0.0006214 , Metrics.MILES);
			
			//转换为2dsphere的距离，这一步非常重要
            Distance d = new Distance(distance, Metrics.MILES);
			//Distance d = new Distance(distance*0.0006214,Metrics.MILES);

			NearQuery nearQuery = NearQuery.near(point).maxDistance(d);
			Criteria[] queryParam = params.toArray(new Criteria[0]);
			final Query query = new Query();
			Paginate page = new Paginate(pageNo, pageSize);
			query.skip(page.getPageIndex() * page.getPageSize());
			query.limit(page.getPageSize());
			
			if (orders != null && orders.size() > 0) {
				query.with(new Sort(orders));
			}
			for (Criteria criteria : queryParam) {
				if (criteria != null) {
					query.addCriteria(criteria);
				}
			}
			nearQuery.query(query);
			//GeoResults<Company> result = dao.findByAddressLocationNear(point, d, Company.class);

			double temp =distance/1000;
			Sphere sphere = new Sphere(point, temp/3963.2);
			List<Company> result = dao.findByLocationNearNew(query,sphere, Company.class);
			/*List<GeoResult<Company>> ls = result.getContent();

			if (CollectionUtils.isNotEmpty(ls)) {
				for (GeoResult<Company> u : ls) {
					list.add(u.getContent());
				}
			}*/
			return result;
		}
		return null;
	}

	@Override
	public void updateCompanyMobile(String companyId, Map<String, Object> obj) {
		dao.saveOrUpdateDocument(Company.class, obj, QueryParamCreator.eq("companyId", companyId));
	}

	@Override
	public List<Position> queryPositionListNews(int pageNo, int pageSize, int queryType, String longitude,
			String latitude) {
		Point point = new Point(Double.valueOf(longitude), Double.valueOf(latitude));

		List<Position> list =new ArrayList<Position>();
		List<Criteria> params = new ArrayList<Criteria>();
		List<Order> orders = new ArrayList<Order>();
		Order order = new Order(Direction.DESC, "createDate");
		orders.add(order);
		NearQuery nearQuery = NearQuery.near(point);
		Criteria[] queryParam = params.toArray(new Criteria[0]);
		final Query query = new Query();
		Paginate page = new Paginate(pageNo, pageSize);
		query.skip(page.getPageIndex() * page.getPageSize());
		query.limit(page.getPageSize());
		
		if (orders != null && orders.size() > 0) {
			query.with(new Sort(orders));
		}
		for (Criteria criteria : queryParam) {
			if (criteria != null) {
				query.addCriteria(criteria);
			}
		}
		nearQuery.query(query);
		
		GeoResults<Position> result = dao.findByLocationNear(nearQuery, Position.class);
		List<GeoResult<Position>> ls = result.getContent();

		if (CollectionUtils.isNotEmpty(ls)) {
			for (GeoResult<Position> u : ls) {
				list.add(u.getContent());
			}
		}
		return list;
	}

	@Override
	public void queryAllPositions() {
		 List<Position> list =dao.getPOList(Position.class);
		 if(!CollectionUtils.isEmpty(list)) {
			 for(Position p:list) {
				 String companyId =p.getCompanyId();
				 
				 Company c = dao.getPO(Company.class, QueryParamCreator.eq("companyId", companyId));
				 if(c !=null) {
					 Map<String, Object> maps =new HashMap<String, Object>();
					 
					 maps.put("latitude", c.getLatitude());
						maps.put("longitude", c.getLongitude());
						
						// 设置location
						double[] a = new double[] { Double.valueOf(c.getLongitude()),
								Double.valueOf(c.getLatitude()) };
						
						maps.put("location", a);
						
						dao.saveOrUpdateDocument(Position.class, maps, QueryParamCreator.eq("companyId", companyId));
				 }
			 }
		 }
	}

	@Override
	public void sethotCompany() {
		 Map<String, Object> maps =new HashMap<String, Object>();
		 maps.put("companyType", 1);
		 dao.saveOrUpdateDocument(Company.class, maps, QueryParamCreator.like("mobile", "199"));
	}

	@Override
	public void updateNewPassword(String mobile, String newpsw) {
		Map<String,Object> map  =new HashMap<String,Object>();
		map.put("newPassword", newpsw);
		dao.saveOrUpdateDocument(Company.class, map, QueryParamCreator.eq("mobile", mobile));
	}
}
